You're working on a secret team solving coded transmissions.
Your team is scrambling to decipher a recent message, worried it's a plot to break into a major European National Cake Vault. The message has been mostly deciphered, but all the words are backward! Your colleagues have handed off the last step to you.
Write a function reverse_words() that takes a message as a list of characters and reverses the order of the words in place.
Why a list of characters instead of a string?
The goal of this question is to practice manipulating strings in place. Since we're modifying the message, we need a mutable type like a list, instead of Python 3.6's immutable strings.
For example:
message = [ 'c', 'a', 'k', 'e', ' ',
'p', 'o', 'u', 'n', 'd', ' ',
's', 't', 'e', 'a', 'l' ]
reverse_words(message)
# Prints: 'steal pound cake'
print(''.join(message))
When writing your function, assume the message contains only letters and spaces, and all words are separated by one space.
We'll write a helper function reverse_characters() that reverses all the characters between a left_index and right_index. We use it to:
def reverse_words(message):
# First we reverse all the characters in the entire message
reverse_characters(message, 0, len(message)-1)
# This gives us the right word order
# but with each word backward
# Now we'll make the words forward again
# by reversing each word's characters
# We hold the index of the *start* of the current word
# as we look for the *end* of the current word
current_word_start_index = 0
for i in range(len(message) + 1):
# Found the end of the current word!
if (i == len(message)) or (message[i] == ' '):
reverse_characters(message, current_word_start_index, i - 1)
# If we haven't exhausted the message our
# next word's start is one character ahead
current_word_start_index = i + 1
def reverse_characters(message, left_index, right_index):
# Walk towards the middle, from both sides
while left_index < right_index:
# Swap the left char and right char
message[left_index], message[right_index] = \
message[right_index], message[left_index]
left_index += 1
right_index -= 1
time and space!
Hmm, the team used your function to finish deciphering the message. There definitely seems to be a heist brewing, but no specifics on where. Any ideas?
How would you handle punctuation?
The naive solution of reversing the words one at a time had a worst-case runtime. That's because swapping words with different lengths required "scooting over" all the other characters to make room.
To get around this "scooting over" issue, we reversed all the characters in the message first. This put all the words in the correct spots, but with the characters in each word backward. So to get the final answer, we reversed the characters in each word. This all takes two passes through the message, so time total.
This might seem like a blind insight, but we derived it by using a clear strategy:
Solve a simpler version of the problem (in this case, reversing the characters instead of the words), and see if that gets us closer to a solution for the original problem.
We talk about this strategy in the "get unstuck" section of our coding interview tips.
Do you have an answer?
Wanna review this one again later? Or do you feel like you got it all?
Mark as done Pin for review laterReset editor
Powered by qualified.io